<?php

namespace app\mobile\controller;

use app\model\Modules;
use think\Db;

class WxappAuth
{
    public function index()
    {
        global $_P, $_G;
        if (!empty($_POST['pdata'])) {
            $str = $_POST['pdata'];
            $key = substr(md5(date("dmY")), 2, 14);
            $decrypt = $this->passport_decrypt($str, $key);

            $_POST['pdata'] = 1;
            if ($decrypt) {
                $decrypt = json_decode($decrypt, true);
                $_POST = array_merge($_POST, $decrypt);
                // $_POST = ihtmlspecialchars($_POST);
            } else {  //解密错误
                http_response_code(501);
                exit(json_encode(['code' => 501, 'msg' => '数据错误']));
            }
        }

        $ip_screen_arr = ['上海', '成都', '广东'];
        $in_ip_screen = false;
        if ($_G['address']) {
            $ip_province = $_G['address']['province'];
            $ip_city = $_G['address']['city'];
            if (in_array($ip_city, $ip_screen_arr) || in_array($ip_province, $ip_screen_arr)) {
                $in_ip_screen = true;
            }
        }
        $fans = ['nickname' => '微信用户'];
        $uniacid = $_P['uniacid'];
        if (!$uniacid) {
            exit('uniacid参数缺失');
        }
        $op = isset($_P['op']) ? $_P['op'] : '';

        $res = Modules::getPlatform($uniacid);
        if ($op == 'getphone') {
            if (!$res) {
                $response = ['code' => 0, 'msg' => '小程序记录不存在', 'data' => []];
                exit(json_encode($response));
            }
        } else {
            if (!$res) {
                exit('公众号记录不存在');
            }
        }

        $call = $_P['call'] ? $_P['call'] : '';
        $scene = $_P['scene'] ? $_P['scene'] : '';
        $pass = $_P['pass'] ? $_P['pass'] : '';
        $id = $_P['id'] ? $_P['id'] : '';
        $type = $_P['type'] ? $_P['type'] : '';
        $callback_path = $_P['callback_path'] ? $_P['callback_path'] : '/pages/index/index';
        if (!$op) {
            //判断是否存在code
            if (isset($_P['code']) && $_P['code']) {
                //请求授权解密 授权信息
                $code = $_P['code'];
                $fans = $this->wechatAuthCallBack($code, $res);
                $return_clicent = ['fans' => $fans, 'call' => $call, 'scene' => $scene, 'pass' => $pass, 'id' => $id, 'type' => $type, 'callback_path' => $callback_path];
                return view('/base/wxapp_auth_jumppage', $return_clicent);
            } else {
                $get_code_url = $this->wechatGetCode($res);
                $return_clicent = get_defined_vars();
                return view('/base/wxapp_auth_jumppage', $return_clicent);
            }
        } else {
            //判断解密手机号
            if ($op == 'getphone') {
                $appid = $res['appid'];
                $appsecret = $res['secret'];
                $code = $_P['loginCode'] ? $_P['loginCode'] : '';
                if (!$code) {
                    $res = ['code' => 0, 'msg' => '参数缺失', 'data' => []];
                    exit(json_encode($res));
                }
                $phone_info = $this->getPhoneNumber($appid, $appsecret, $code);
                if ($phone_info['code'] != 0) {
                    $res = ['code' => $phone_info['code'], 'msg' => $phone_info['msg'], 'data' => []];
                    exit(json_encode($res));
                } else {
                    $res = ['code' => 1, 'msg' => 'ok', 'data' => $phone_info['data']['purePhoneNumber']];
                    exit(json_encode($res));
                }
            }
        }
    }

    public function wechatGetCode($res)
    {
        $appid = $res['appid'];
//    $redirect_url = 'https://kaifa.yixuan.net/app/webview/inc/webview.php?do=yxauth';
//            $redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

        $redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

        $serverconfigs = Db::name('00serverconfig')->where(['id' => 1])->find();
        $serverconfig = !empty($serverconfigs['settings']) ? xunserializer($serverconfigs['settings']) : array();
        if ($_SERVER['HTTP_HOST'] != $serverconfig['domain1'] && $serverconfig['domain1'] != "www.yixuan.net" && DOMAIN0 != "19.yixuan.net") {
            $string = DOMAIN0 . ',' . $serverconfig['domain2'] . "," . $serverconfig['domain3'] . "," . $serverconfig['domainsq'] . "," . $serverconfig['domainfx'] . "," . $serverconfig['domainyg'] . "," . $serverconfig['domainsqby'] . "," . $serverconfig['domainfxby'];
            if (strstr($string, $_SERVER['HTTP_HOST']) !== false) {
                $url = $_SERVER['REQUEST_URI'];
                $redirect_url = "https://" . $serverconfig['domain1'] . $url;
            }
        }
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $appid . "&redirect_uri=" . urlencode($redirect_url) . "&response_type=code&scope=snsapi_userinfo&state=1&forcePopup=true#wechat_redirect";
        return $url;
    }

    public function wechatAuthCallBack($code = '', $res)
    {
        if ($code) {
            $app_id = $res['appid'];
            $app_secret = $res['secret'];
            $data = $this->curl('https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $app_id . '&secret=' . $app_secret . '&code=' . $code . '&grant_type=authorization_code');
            $data = json_decode($data);
            if ($data->errcode) {
                halt($data->errmsg);
            }
            if (isset($data->openid) && $data->openid) {
                $open_id = $data->openid;
                $access_token = $data->access_token;
                $user_info = $this->curl('https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $open_id . '&lang=zh_CN');
                $user_info = json_decode($user_info);
                $user_openid = $user_info->openid;
                $user_nickname = $user_info->nickname;
                $user_headimgurl = $user_info->headimgurl;
                $user_unionid = $user_info->unionid;
                $user_nickname = stripcslashes($this->filterEmoji($user_nickname));
                if (empty($user_nickname)) {
                    $user_nickname = '无';
                }
                return ['avatar' => $user_headimgurl, 'nickname' => $user_nickname];
            }
        } else {
            halt('code not exist');

        }
    }

    public function filterEmoji($str)
    {
        $str = preg_replace_callback(
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
        return $str;
    }

    public function curl($url, $post = false, $header = [])
    {
        $headerArray = array_merge($header, [
            'Expect:',
        ]);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($post) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        }
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }

    public function getPhoneNumber($appid, $appsecret, $code)
    {
        $access_token = $this->getAccessToken($appid, $appsecret);
        $url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" . $access_token;
        $data = $this->curl($url, json_encode(['code' => $code]), array('Content-Type: application/json'));
        $data = json_decode($data, true);
        if ($data['errcode'] != 0) {
            return ['code' => $data['errcode'], 'msg' => $data['errmsg'], 'data' => []];
        } else {
            return ['code' => 0, 'msg' => 'ok', 'data' => $data['phone_info']];
        }

    }

    public function getAccessToken($appid, $appsecret)
    {
        // TODO
        $cachekey = cache_system_key('accesstoken_key', array('appid' => $appid));
        $cache = cache_load($cachekey);
        if (!empty($cache) && !empty($cache['token']) && $cache['expire'] > TIMESTAMP) {
            return $cache['token'];
        }

        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
        $ch1 = curl_init();
        curl_setopt($ch1, CURLOPT_URL, $url);
        curl_setopt($ch1, CURLOPT_POST, 1);
        curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch1, CURLOPT_POSTFIELDS, '');
        $c = curl_exec($ch1);
        $response = @json_decode($c, true);
        $res = array();
        $res['token'] = $response['access_token'];
        $res['expire'] = TIMESTAMP + $response['expires_in'] - 600;
        cache_write($cachekey, $res);
        return $res['token'];
    }


    public function passport_decrypt($txt, $key = '')
    {
        $md5 = substr($txt, 0, 6) . substr($txt, -26);
        $txt = substr($txt, 6, strlen($txt) - 32);
        if ($md5 != md5($txt)) {
            return;
        }

        $txt = $this->encrypt(base64_decode(urldecode($txt)), 'D', $key);

        if (substr($txt, 0, 10) != 0 && substr($txt, 0, 10) - time() < 0) {
            return;
        }
        $txt = $this->passport_key(substr($txt, 10), $key);
        $tmp = '';
        for ($i = 0; $i < strlen($txt); $i++) {
            $md5 = $txt[$i];
            $tmp .= $txt[++$i] ^ $md5;
        }
        $tmp = urldecode($tmp);
        return $tmp;
    }

    public function passport_key($txt, $encrypt_key)
    {
        $encrypt_key = md5($encrypt_key);
        $ctr = 0;
        $tmp = '';

        for ($i = 0; $i < strlen($txt); $i++) {
            $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
            $tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
        }
        return $tmp;
    }

//函数encrypt($string,$operation,$key)中$string：需要加密解密的字符串；$operation：判断是加密还是解密，E表示加密，D表示解密；$key：密匙。
    public function encrypt($string, $operation, $key = 'yixuan')
    {
        $key = md5($key);
        $key_length = strlen($key);
        $string = $operation == 'D' ? utf8_decode(base64_decode($string)) : substr(md5($string . $key), 0, 8) . $string;
        $string_length = strlen($string);
        $rndkey = $box = array();
        $result = '';
        for ($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($key[$i % $key_length]);
            $box[$i] = $i;
        }

        for ($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        for ($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));

        }
        if ($operation == 'D') {
            if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
                return substr($result, 8);
            } else {
                return '';
            }
        } else {
            return str_replace('=', '', base64_encode(utf8_encode($result)));
        }
    }
}

    